
local ScrollBar = commonlib.inherit(commonlib.ToolBase);

ScrollBar:Property("Blockly");
ScrollBar:Property("Direction");             -- 方向        -- horizontal  vertical 

function ScrollBar:ctor()
    self.__track_width__, self.__track_height__ = 0, 0;
    self.__width__, self.__height__ = 0, 0;
end

function ScrollBar:Init(blockly, direction)
    self:SetBlockly(blockly);
    self:SetDirection(direction);
    return self;
end

function ScrollBar:IsHorizontal()
    return self:GetDirection() == "horizontal";
end

function ScrollBar:GetScrollBarSize()
    return 2 * self:GetBlockly():GetUnitSize();
end

function ScrollBar:OnScroll()
    local blockly = self:GetBlockly();
    local ScrollBarSize = self:GetScrollBarSize();
    local toolboxWidth = blockly:GetToolBoxWidth();
    local width, height = blockly:GetWidthHeight();
    local UnitSize = blockly:GetUnitSize();
    self.__toolbox_width__ = toolboxWidth;
    self.__track_width__, self.__track_height__ = width - self.__toolbox_width__, height;

    if (#(blockly.__block_list__) == 0) then return end 

    local __content_left_unit_count__, __content_top_unit_count__, __content_right_unit_count__, __content_bottom_unit_count__ = blockly.__min_offset_x_count__, blockly.__min_offset_y_count__, blockly.__max_offset_x_count__, blockly.__max_offset_y_count__;
    local __offset_x_unit_count__, __offset_y_unit_count__ = blockly.__offset_x_unit_count__, blockly.__offset_y_unit_count__;
    local __view_width_unit_count__, __view_height_unit_count__ = math.floor(self.__track_width__ / UnitSize), math.floor(self.__track_height__ / UnitSize); 

    local __content_width_unit_count__ = __content_right_unit_count__ - __content_left_unit_count__;
    local __content_height_unit_count__ = __content_bottom_unit_count__ - __content_top_unit_count__;
    local __content_offset_x_unit_count__ = __offset_x_unit_count__ - __content_left_unit_count__;
    local __content_offset_y_unit_count__ = __offset_y_unit_count__ - __content_top_unit_count__;

    self.__content_left_unit_count__, self.__content_top_unit_count__, self.__content_right_unit_count__, self.__content_bottom_unit_count__ = __content_left_unit_count__, __content_top_unit_count__, __content_right_unit_count__, __content_bottom_unit_count__;
    self.__content_width_unit_count__, self.__content_height_unit_count__ = __content_width_unit_count__, __content_height_unit_count__;
    self.__content_offset_x_unit_count__, self.__content_offset_y_unit_count__ = __content_offset_x_unit_count__, __content_offset_y_unit_count__;
    self.__view_width_unit_count__, self.__view_height_unit_count__ = __view_width_unit_count__, __view_height_unit_count__;
    if (self:IsHorizontal()) then
        self.__width__, self.__height__ = math.floor(self.__track_width__ * self.__track_width__ / (self.__content_width_unit_count__ * UnitSize + self.__track_width__)), ScrollBarSize;
        self.__offset_x__, self.__offset_y__ = self.__toolbox_width__ + math.floor(self.__track_width__ * self.__content_offset_x_unit_count__ * UnitSize / (self.__content_width_unit_count__ * UnitSize + self.__track_width__)), self.__track_height__ - self.__height__ - 1;
    else
        self.__width__, self.__height__ = ScrollBarSize, math.floor(self.__track_height__ * self.__track_height__ / (self.__content_height_unit_count__ * UnitSize + self.__track_height__));
        self.__offset_x__, self.__offset_y__ = self.__toolbox_width__ + self.__track_width__ - self.__width__ - 1, math.floor(self.__track_height__ * (self.__content_offset_y_unit_count__ * UnitSize / (self.__content_height_unit_count__ * UnitSize + self.__track_height__)));
    end
end

function ScrollBar:Render(painter)
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();

    -- invisible
    if (self.__width__ == 0 or self.__height__ == 0) then return end 

    -- track
    blockly:SetBrushColor(0xffffffff);
    if (self:IsHorizontal()) then
        blockly:DrawRectangle(self.__toolbox_width__, self.__track_height__ - self.__height__ - 2, self.__track_width__, self.__height__ + 2);
    else
        blockly:DrawRectangle(self.__toolbox_width__ + self.__track_width__ - self.__width__ - 2, 0, self.__width__ + 2, self.__track_height__);
    end
    -- thumb
    blockly:SetBrushColor(0xcececeff);
    blockly:DrawRectangle(self.__offset_x__, self.__offset_y__, self.__width__, self.__height__);
end

function ScrollBar:GetMouseUI(x, y)
    local blockly = self:GetBlockly();
    x = x - blockly:GetToolBoxWidth();
    if (x < 0 or y < 0) then return nil end
    if (self:IsHorizontal()) then
        if (y < self.__track_height__ and y > (self.__track_height__ - self.__height__ - 2)) then return self end 
    else
        if (x < self.__track_width__ and x > (self.__track_width__ - self.__width__ - 2)) then return self end 
    end
    return nil;
end

function ScrollBar:OnMouseDown(event)
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    local x, y = blockly:ScreenXYToElementXY(event:GetXY());

    if (self:IsHorizontal()) then
        if (x > self.__offset_x__ and x < (self.__offset_x__ + self.__width__)) then
            self.__drag_mouse_x__, self.__drag_mouse_y__ = event:GetXY();
            self.__draw_offset_x__, self.__drag_offset_y__ = self.__offset_x__, self.__offset_y__;
            self.__draging__ = true;
        else
            self.__draging__ = false;
            self.__offset_x__ = x;
            local __content_offset_x_unit_count__ = (self.__content_width_unit_count__ + self.__view_width_unit_count__) * (self.__offset_x__ - self.__toolbox_width__) / (self.__view_width_unit_count__ * UnitSize);
            __content_offset_x_unit_count__ = math.max(__content_offset_x_unit_count__, 0);
            __content_offset_x_unit_count__ = math.min(__content_offset_x_unit_count__, self.__content_width_unit_count__);
            local __offset_x_unit_count__ = __content_offset_x_unit_count__ + self.__content_left_unit_count__; 
            blockly.__offset_x_unit_count__ = __offset_x_unit_count__;
            blockly.__offset_x__ = __offset_x_unit_count__ * UnitSize;
        end
    else 
        if (y > self.__offset_y__ and y < (self.__offset_y__ + self.__height__)) then
            self.__drag_mouse_x__, self.__drag_mouse_y__ = event:GetXY();
            self.__draw_offset_x__, self.__drag_offset_y__ = self.__offset_x__, self.__offset_y__;
            self.__draging__ = true;
        else
            self.__draging__ = false;
            self.__offset_y__ = y;
            local __content_offset_y_unit_count__ = (self.__content_height_unit_count__ + self.__view_height_unit_count__) * (self.__offset_y__ / (self.__track_height__));
            __content_offset_y_unit_count__ = math.max(__content_offset_y_unit_count__, 0);
            __content_offset_y_unit_count__ = math.min(__content_offset_y_unit_count__, self.__content_height_unit_count__);
            local __offset_y_unit_count__ = __content_offset_y_unit_count__ + self.__content_top_unit_count__; 
            blockly.__offset_y_unit_count__ = __offset_y_unit_count__;
            blockly.__offset_y__ = __offset_y_unit_count__ * UnitSize;
        end
    end
end

function ScrollBar:OnMouseMove(event)
    if (not self.__draging__) then return end
    local blockly = self:GetBlockly();
    local UnitSize = blockly:GetUnitSize();
    local __drag_mouse_x__, __drag_mouse_y__ = event:GetXY();
    if (self:IsHorizontal()) then
        local __offset_x__ = __drag_mouse_x__ - self.__drag_mouse_x__;
        self.__offset_x__ = self.__draw_offset_x__ + __offset_x__;
        self.__offset_x__ = math.max(self.__toolbox_width__, self.__offset_x__);
        self.__offset_x__ = math.min(self.__offset_x__, self.__track_width__ + self.__toolbox_width__ - self.__width__);
        local __content_offset_x_unit_count__ = (self.__content_width_unit_count__ + self.__view_width_unit_count__) * (self.__offset_x__ - self.__toolbox_width__) / (self.__view_width_unit_count__ * UnitSize);
        __content_offset_x_unit_count__ = math.max(__content_offset_x_unit_count__, 0);
        __content_offset_x_unit_count__ = math.min(__content_offset_x_unit_count__, self.__content_width_unit_count__);
        local __offset_x_unit_count__ = __content_offset_x_unit_count__ + self.__content_left_unit_count__; 
        blockly.__offset_x_unit_count__ = __offset_x_unit_count__;
        blockly.__offset_x__ = __offset_x_unit_count__ * UnitSize;
    else
        local __offset_y__ = __drag_mouse_y__ - self.__drag_mouse_y__;
        self.__offset_y__ = self.__drag_offset_y__ + __offset_y__;
        self.__offset_y__ = math.max(0, self.__offset_y__);
        self.__offset_y__ = math.min(self.__offset_y__, self.__track_height__ - self.__height__);
        local __content_offset_y_unit_count__ = (self.__content_height_unit_count__ + self.__view_height_unit_count__) * (self.__offset_y__ / (self.__track_height__));
        __content_offset_y_unit_count__ = math.max(__content_offset_y_unit_count__, 0);
        __content_offset_y_unit_count__ = math.min(__content_offset_y_unit_count__, self.__content_height_unit_count__);
        local __offset_y_unit_count__ = __content_offset_y_unit_count__ + self.__content_top_unit_count__; 
        blockly.__offset_y_unit_count__ = __offset_y_unit_count__;
        blockly.__offset_y__ = __offset_y_unit_count__ * UnitSize;
    end
end

function ScrollBar:OnMouseUp(event)
    self.__draging__ = false;
end

return ScrollBar;